package com.tutorial.mock;

import com.tutorial.advice.MyAdvice;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 模拟AOP
 * className: MockAopBeanPostProcessor
 * author: GXW
 * date: 2025/7/21 14:49:50
 * description: TODO 模拟AOP
 */
public class MockAopBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {
	private ApplicationContext applicationContext;

	/**
	 * @param bean     the new bean instance
	 * @param beanName the name of the bean
	 * @return
	 * @throws BeansException
	 */
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// 目的：对UserServiceImpl中的show1和show2方法进行增强，增强的方法存在于MyAdvice中
		// 问题1：筛选service.impl包下所有的方法都可以进行增强，解决方案：if-else
		// 问题2：MyAdvice怎么获取？解决方案：从Spring容器中获取MyAdvice
		if (bean.getClass().getPackage().getName().equals("com.tutorial.service.impl")) {
			// 	生成当前Bean的Proxy对象
			Object beanProxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), (Object proxy, Method method, Object[] args) -> {
				MyAdvice myAdvice = applicationContext.getBean(MyAdvice.class);
				// 执行增强对象的before方法
				myAdvice.beforeAdvice();
				// 执行目标对象的目标方法
				Object result = method.invoke(bean, args);
				// 执行增强对象的after方法
				// myAdvice.afterAdvice();
				return result;
			});
			return beanProxy;
		}
		return bean;
	}

	/**
	 * @param applicationContext the ApplicationContext object to be used by this object
	 * @throws BeansException
	 */
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}
}
